home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Super OZ Shareware: Games
/
SuperOZ Shareware, Games Volume 1.iso
/
BOARD
/
HANG-MAN.ZIP
/
HANGMAN.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-03-26
|
43KB
|
1,374 lines
PROGRAM Hangman(INPUT, OUTPUT, PlacEasy, PlacMedm, PlacHard, ThngEasy, ThngMedm, ThngHard, PeplEasy, PeplMedm, PeplHard);
USES CRT,GRAPH;
{$M 65520,0,655360}
(* This program is designed to be an easy-to-use, easy-to explain
game to be used by young children. It can be used by people of
all ages, but it is specifically designed for a young age group.
Program Designed by: Jeremy Gerlach
Date Started : February 16, 1993
Date Completed : March 23, 1993
Client : Prof. Gary Locklair
Version : 1.5
I.D.# : 500037
In-House Name : Hang Him *)
(*------------------------ Code Starts Here ------------------------*)
(*----------------------- User Defined Codes -----------------------*)
CONST
Esc = #27;
F1 = #59;
F2 = #60;
MaxGuesses = 40;
MaxWordChoices = 70;
TYPE
GuessIndexType = 1..MaxGuesses;
WordIndexType = 1..MaxWordChoices;
StringType1 = STRING[1];
StringType32 = STRING[32];
WordRecType = RECORD
EasyPlaces,
MediumPlaces,
HardPlaces,
EasyThings,
MediumThings,
HardThings,
EasyPeople,
MediumPeople,
HardPeople: StringType32
END;
CorrectGuessArrayType = ARRAY [1..32] OF StringType1;
WordRecArrayType = ARRAY[WordIndexType] OF WordRecType;
GuessArrayType = ARRAY[GuessIndexType] OF CHAR;
VAR
GuessArray:
GuessArrayType;
Continue,
EntryError:
BOOLEAN;
WordRecArray:
WordRecArrayType;
Category,
NextScreen,
PlayAgain,
DifficultyLevel:
CHAR;
WordToBeGuessed:
StringType32;
NumGuesses:
INTEGER;
(***************************** Procedures ***************************)
(*----------------------------------------------------------------*)
PROCEDURE Introduction(VAR WordRecArray:
WordRecArrayType;
NextScreen:
CHAR );
(* This procedure first reads the word files into an array of records. *)
(* Then the user is welcomed to the program. *)
VAR
EasyPlaceIn,
MediumPlaceIn,
HardPlaceIn,
EasyThingIn,
MediumThingIn,
HardThingIn,
EasyPeopleIn,
MediumPeopleIn,
HardPeopleIn:
TEXT;
Count:
INTEGER;
BEGIN
ASSIGN (EasyPlaceIn, 'PlacEasy.WRD');
ASSIGN (MediumPlaceIn, 'PlacMedm.WRD');
ASSIGN (HardPlaceIn, 'PlacHard.WRD');
ASSIGN (EasyThingIn, 'ThngEasy.WRD');
ASSIGN (MediumThingIn, 'ThngMedm.WRD');
ASSIGN (HardThingIn, 'ThngHard.WRD');
ASSIGN (EasyPeopleIn, 'PeplEasy.WRD');
ASSIGN (MediumPeopleIn, 'PeplMedm.WRD');
ASSIGN (HardPeopleIn, 'PeplHard.WRD');
RESET (EasyPlaceIn);
RESET (MediumPlaceIn);
RESET (HardPlaceIn);
RESET (EasyThingIn);
RESET (MediumThingIn);
RESET (HardThingIn);
RESET (EasyPeopleIn);
RESET (MediumPeopleIn);
RESET (HardPeopleIn);
(* Array of records of words is filled with this FOR loop. *)
FOR Count := 1 TO 70 DO
BEGIN
READLN (EasyPlaceIn, WordRecArray[Count].EasyPlaces);
READLN (MediumPlaceIn, WordRecArray[Count].MediumPlaces);
READLN (HardPlaceIn, WordRecArray[Count].HardPlaces);
READLN (EasyThingIn, WordRecArray[Count].EasyThings);
READLN (MediumThingIn, WordRecArray[Count].MediumThings);
READLN (HardThingIn, WordRecArray[Count].HardThings);
READLN (EasyPeopleIn, WordRecArray[Count].EasyPeople);
READLN (MediumPeopleIn, WordRecArray[Count].MediumPeople);
READLN (HardPeopleIn, WordRecArray[Count].HardPeople)
END;
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('WELCOME to the game of Hangman. This game is meant to provide fun');
WRITELN('for people of all ages. Hangman is easy to play and understand.');
WRITELN;
WRITELN(' If you need any help at any time during the game simply press');
WRITELN('function key 1 (F1). This is the help key. It will provide you');
WRITELN('with helpful information on how to proceed.');
WRITELN;
WRITELN;
WRITELN(' Enjoy your game!!');
WRITELN;
WRITELN;
WRITELN;
WRITELN('Press any key to continue.');
NextScreen := READKEY;
IF (NextScreen = #0)
THEN
NextScreen := READKEY
END;
(*----------------------------------------------------------------*)
PROCEDURE CategoryHelp ( NextScreen:
CHAR );
(* This procedure provides some help insight *)
(* in choosing a category. *)
BEGIN
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('The choice you must make is the type of word that you want to guess.');
WRITELN('If you wish to guess a place, you must choose that by pressing the number 1.');
WRITELN('You can choose to guess a thing by pressing the number 2.');
WRITELN('You can choose to guess a person just by pressing the number 3.');
WRITELN('The final category you can choose is miscellaneous.');
WRITELN('This category includes all of the words from the first three categories.');
WRITELN('You could get any word to guess if you choose miscellaneous.');
WRITELN('Choose this category by pressing the number 4.');
WRITELN;
WRITELN;
WRITELN('Press any key to make your choice.');
NextScreen := READKEY;
IF (NextScreen = #0)
THEN
NextScreen := READKEY
END;
(*----------------------------------------------------------------*)
PROCEDURE DifficultyLevelHelp ( NextScreen:
CHAR );
(* This procedure provides some helpful insight *)
(* to the user on choosing a difficulty level. *)
BEGIN
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('Now you get to choose the difficulty level of the word you are going to guess.');
WRITELN('There are three difficulty levels to choose from: Easy, Medium, and Hard.');
WRITELN('The Easy difficulty level for the most part has short words.');
WRITELN('And the Hard difficulty level has long words. It follows that the');
WRITELN('Medium difficulty level has words that are in between long and short.');
WRITELN('You can choose the Easy difficulty level just by pressing the number 1.');
WRITELN('You can choose the Medium difficulty level simply by pressing the number 2.');
WRITELN('And the Hard difficulty level can be played by pressing the number 3.');
WRITELN;
WRITELN;
WRITELN('Press any key to make your choice.');
NextScreen := READKEY;
IF (NextScreen = #0)
THEN
NextScreen := READKEY
END;
(*----------------------------------------------------------------*)
PROCEDURE PlayAgainHelp ( NextScreen:
CHAR );
(* This procedure provides some helpful insight *)
(* to the user on deciding to play again or not. *)
BEGIN
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('You must choose whether or not you want to play another game of Hangman.');
WRITELN('If you do want to play again you can simply press the letter "Y" for yes.');
WRITELN('Or if you do not want to play again you can just press the letter "N" for no.');
WRITELN('It does not need to be a capital "Y" or "N".');
WRITELN('You must just press one or the other.');
WRITELN;
WRITELN;
WRITELN('Press any key to make your choice.');
NextScreen := READKEY;
IF (NextScreen = #0)
THEN
NextScreen := READKEY
END;
(*----------------------------------------------------------------*)
PROCEDURE Options (VAR Category,
DifficultyLevel,
NextScreen:
CHAR;
EntryError,
Continue:
BOOLEAN );
(* This procedure obtains the user's choice of category and difficulty level. *)
BEGIN
(* This is where the category menu is displayed *)
(* and the user's choice is obtained. *)
EntryError := FALSE;
REPEAT
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN;
WRITELN('What category would you like?');
WRITELN;
WRITELN(' 1. PLACES');
WRITELN(' 2. THINGS');
WRITELN(' 3. PEOPLE');
WRITELN(' 4. MISCELLANEOUS');
WRITELN;
IF (EntryError) (* Displays error message if needed. *)
THEN
BEGIN
WRITELN('You have entered an incorrect choice.');
WRITELN('Please reenter your choice (1, 2, 3, 4, or F1 for help).')
END
ELSE
WRITELN('Please enter your choice (1, 2, 3, 4, or F1 for help).');
Category := READKEY;
IF (Category = #0)
THEN
BEGIN
Category := READKEY;
IF (Category = F1) (* Checks if the user asked for help. *)
THEN
BEGIN
CategoryHelp(NextScreen);
EntryError := FALSE;
Continue := FALSE
END
END
ELSE IF ((Category >= '1') AND (Category <= '4'))
THEN
BEGIN
EntryError := FALSE; (* Makes sure category is *)
Continue := TRUE (* in the correct range. *)
END
ELSE
BEGIN
EntryError := TRUE;
Continue := FALSE
END;
UNTIL (Continue);
(* This is where the difficulty level is displayed *)
(* and the user's choice of difficulty level is obtained. *)
REPEAT
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('What difficulty level would you like to start at?');
WRITELN;
WRITELN(' 1. EASY');
WRITELN(' 2. MEDIUM');
WRITELN(' 3. HARD');
WRITELN;
IF (EntryError) (* Displays error message if needed. *)
THEN
BEGIN
WRITELN('You have entered an incorrect choice.');
WRITELN('Please reenter your choice (1, 2, 3, or F1 for help).')
END
ELSE
WRITELN('Please enter your choice (1, 2, 3, or F1 for help).');
DifficultyLevel := READKEY;
IF (DifficultyLevel = #0)
THEN
BEGIN
DifficultyLevel := READKEY;
IF (DifficultyLevel = F1) (* Checks if user asked for help. *)
THEN
BEGIN
DifficultyLevelHelp(NextScreen);
EntryError := FALSE;
Continue := FALSE
END
END
ELSE IF ((DifficultyLevel >= '1') AND (DifficultyLevel <= '3'))
THEN
BEGIN
EntryError := FALSE; (* Makes sure that user's choice *)
Continue := TRUE; (* is in the range. *)
END
ELSE
BEGIN
EntryError := TRUE;
Continue := FALSE
END;
UNTIL (Continue)
END;
(*----------------------------------------------------------------*)
PROCEDURE GetWord (VAR WordToBeGuessed:
StringType32;
Category,
DifficultyLevel:
CHAR;
WordRecArray:
WordRecArrayType );
(* This procedure is one big IF-THEN-ELSE statement. *)
(* It gets word which the user will guess using a random number *)
(* and the user's choice of category and difficulty level. *)
VAR
RandomCategory,
RandomNum:
INTEGER;
BEGIN
CLRSCR;
RANDOMIZE;
RandomNum := RANDOM(70) + 1;
IF (Category = '1')
THEN
BEGIN
IF (DifficultyLevel = '1')
THEN
WordToBeGuessed := WordRecArray[RandomNum].EasyPlaces
ELSE IF (DifficultyLevel = '2')
THEN
WordToBeGuessed := WordRecArray[RandomNum].MediumPlaces
ELSE
WordToBeGuessed := WordRecArray[RandomNum].HardPlaces
END
ELSE IF (Category = '2')
THEN
BEGIN
IF (DifficultyLevel = '1')
THEN
WordToBeGuessed := WordRecArray[RandomNum].EasyThings
ELSE IF (DifficultyLevel = '2')
THEN
WordToBeGuessed := WordRecArray[RandomNum].MediumThings
ELSE
WordToBeGuessed := WordRecArray[RandomNum].HardThings
END
ELSE IF (Category = '3')
THEN
BEGIN
IF (DifficultyLevel = '1')
THEN
WordToBeGuessed := WordRecArray[RandomNum].EasyPeople
ELSE IF (DifficultyLevel = '2')
THEN
WordToBeGuessed := WordRecArray[RandomNum].MediumPeople
ELSE
WordToBeGuessed := WordRecArray[RandomNum].HardPeople
END
ELSE
BEGIN
RANDOMIZE;
RandomCategory := RANDOM(3) + 1;
IF (RandomCategory = 1)
THEN
BEGIN
IF (DifficultyLevel = '1')
THEN
WordToBeGuessed := WordRecArray[RandomNum].EasyPlaces
ELSE IF (DifficultyLevel = '2')
THEN
WordToBeGuessed := WordRecArray[RandomNum].MediumPlaces
ELSE
WordToBeGuessed := WordRecArray[RandomNum].HardPlaces
END
ELSE IF (RandomCategory = 2)
THEN
BEGIN
IF (DifficultyLevel = '1')
THEN
WordToBeGuessed := WordRecArray[RandomNum].EasyThings
ELSE IF (DifficultyLevel = '2')
THEN
WordToBeGuessed := WordRecArray[RandomNum].MediumThings
ELSE
WordToBeGuessed := WordRecArray[RandomNum].HardThings
END
ELSE IF (RandomCategory = 3)
THEN
BEGIN
IF (DifficultyLevel = '1')
THEN
WordToBeGuessed := WordRecArray[RandomNum].EasyPeople
ELSE IF (DifficultyLevel = '2')
THEN
WordToBeGuessed := WordRecArray[RandomNum].MediumPeople
ELSE
WordToBeGuessed := WordRecArray[RandomNum].HardPeople
END
END
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawStand;
BEGIN
(*--------------------------Base---------------------------*)
SETCOLOR (6); (*Brown*)
RECTANGLE (450, 370, 580, 430);(*Box*)
LINE (450, 370, 470, 340);
LINE (470, 340, 515, 340);
LINE (539, 340, 600, 340);
LINE (580, 370, 600, 340); (*3d Box*)
LINE (600, 340, 600, 400);
LINE (600, 400, 580, 430);
RECTANGLE (515, 100, 535, 353); (*Vertical Pole*)
LINE (515, 100, 519, 94);
LINE (519, 94, 539, 94);
LINE (535, 353, 539, 347); (*3d Vertical Pole*)
LINE (539, 347, 539, 94);
LINE (535, 100, 539, 94);
RECTANGLE (360, 100, 515, 120); (*Horizontal Pole*)
LINE (360, 100, 364, 94);
LINE (364, 94, 519, 94); (*3d Horizontal Pole*)
LINE (450, 120, 515, 185); (*Crossbar Support*)
LINE (465, 120, 515, 170);
LINE (470, 120, 515, 165); (*3d Crossbar Support*)
SETCOLOR (14); (*Yellow*)
LINE (380, 121, 380, 140); (*Rope*);
SETCOLOR (15) (*White*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawHead;
BEGIN
CIRCLE (380, 170, 30); (*Head*)
CIRCLE (365, 155, 3); (*Right Eye*)
CIRCLE (395, 155, 3); (*Left Eye*)
CIRCLE (380, 170, 3); (*Nose*)
LINE (365, 185, 395, 185); (*Mouth*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawBody;
BEGIN
LINE (380, 200, 380, 300);(*Body*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawRightArm;
BEGIN
LINE (380, 220, 340, 280);(*Right Arm*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawLeftArm;
BEGIN
LINE (380, 220, 420, 280);(*Left Arm*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawRightLeg;
BEGIN
LINE (380, 300, 340, 385);(*Right Leg*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawLeftLeg;
BEGIN
LINE (380, 300, 420, 385);(*Left Leg*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawHands;
BEGIN
CIRCLE (336, 284, 5);(*Right Hand*)
CIRCLE (424, 284, 5);(*Left Hand*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawFeet;
BEGIN
CIRCLE (335, 390, 8);(*Right Foot*)
CIRCLE (425, 390, 8);(*Left Foot*)
END;
(*----------------------------------------------------------------*)
PROCEDURE DrawHangmanParts ( NumPartsHangman:
INTEGER );
(* This procedure determines which part of the hangman should be drawn. *)
BEGIN
IF (NumPartsHangman = 0)
THEN
DrawStand
ELSE IF (NumPartsHangman = 1)
THEN
DrawHead
ELSE IF (NumPartsHangman = 2)
THEN
DrawBody
ELSE IF (NumPartsHangman = 3)
THEN
DrawRightArm
ELSE IF (NumPartsHangman = 4)
THEN
DrawLeftArm
ELSE IF (NumPartsHangman = 5)
THEN
DrawRightLeg
ELSE IF (NumPartsHangman = 6)
THEN
DrawLeftLeg
ELSE IF (NumPartsHangman = 7)
THEN
DrawHands
ELSE DrawFeet
END;
(*----------------------------------------------------------------*)
PROCEDURE SetUp (VAR NumPartsHangman,
NumCorrectGuesses,
WordLength:
INTEGER;
Category,
DifficultyLevel:
CHAR;
WordToBeGuessed:
StringType32;
VAR CorrectGuessArray:
CorrectGuessArrayType);
(* This procedure sets up the graphics screen for hangman. *)
TYPE
StringType13 = STRING[13];
VAR
CategoryName,
DifficultyLevelName:
StringType13;
Count,
StringPosition,
VideoAdapter,
VideoMode:
INTEGER;
TempLetter:
StringType1;
BEGIN
(* This IF statement defines CategoryName and DifficultyLevelName *)
(* so that the category and difficulty level can be displayed on the screen. *)
IF (Category = '1')
THEN
CategoryName := 'PLACES'
ELSE IF (Category = '2')
THEN
CategoryName := 'THINGS'
ELSE IF (Category = '3')
THEN
CategoryName := 'PEOPLE'
ELSE CategoryName := 'MISCELLANEOUS';
IF (DifficultyLevel = '1')
THEN
DifficultyLevelName := 'EASY'
ELSE IF (DifficultyLevel = '2')
THEN
DifficultyLevelName := 'MEDIUM'
ELSE DifficultyLevelName := 'HARD';
NumPartsHangman := 0;
NumCorrectGuesses := 0;
VideoAdapter := VGA;
VideoMode := VGAHi;
INITGRAPH (VideoAdapter, VideoMode,'');
SETCOLOR (WHITE);
DrawHangmanParts (NumPartsHangman);
NumPartsHangman := NumPartsHangman + 1;
MOVETO (1, 300);
WordLength := LENGTH (WordToBeGuessed);
FOR StringPosition := 1 TO WordLength DO (* Displays word to be guessed *)
BEGIN (* as a series of dashes. *)
TempLetter := COPY (WordToBeGuessed, StringPosition, 1);
IF ((TempLetter = ' ') OR (TempLetter = ',') OR (TempLetter = '.'))
THEN
BEGIN
OUTTEXT (TempLetter);
NumCorrectGuesses := NumCorrectGuesses + 1;
CorrectGuessArray[NumCorrectGuesses] := TempLetter
END
ELSE
OUTTEXT ('-')
END;
OUTTEXTXY (1, 400, 'Please enter a letter for your guess.');
OUTTEXTXY (1, 420, '(F1 for a hint. F2 to guess the whole word.)');
OUTTEXTXY (1, 440, '?');
SETCOLOR (GREEN);
OUTTEXTXY (1, 80, 'Category : ' + CategoryName);
OUTTEXTXY (1, 100, 'Difficulty Level : ' + DifficultyLevelName);
SETCOLOR (WHITE)
END;
(*----------------------------------------------------------------*)
PROCEDURE LetterHint( WordToBeGuessed:
StringType32;
CorrectGuessArray:
CorrectGuessArrayType;
GuessArray:
GuessArrayType;
WordLength,
NumCorrectGuesses,
NumGuesses:
INTEGER );
(* This procedure gives the user some hints on what to guess. *)
(* Three letters are displayed. One is correct and the other two are incorrect. *)
CONST
AlphabetLength = 26;
TYPE
StringType26 = STRING[26];
VAR
Alphabet:
StringType26;
TempLetter,
WrongHintLetter1,
WrongHintLetter2,
CorrectHintLetter:
StringType1;
Loop:
BOOLEAN;
Count,
RandomNum:
INTEGER;
BEGIN
Alphabet := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
REPEAT
Loop := FALSE; (* Makes sure the letter chosen *)
RANDOMIZE; (* is not already displayed. *)
RandomNum := RANDOM(WordLength) + 1;
CorrectHintLetter := COPY (WordToBeGuessed, RandomNum, 1);
FOR Count := 1 TO NumCorrectGuesses DO
BEGIN
IF (CorrectHintLetter = CorrectGuessArray[Count])
THEN
Loop := TRUE
END;
UNTIL NOT(Loop);
REPEAT
Loop := FALSE; (* Makes sure letter chosen is not *)
RANDOMIZE; (* correct or already guessed. *)
RandomNum := RANDOM(AlphabetLength) + 1;
WrongHintLetter1 := COPY (Alphabet, RandomNum, 1);
IF (WrongHintLetter1 = CorrectHintLetter)
THEN
Loop := TRUE;
FOR Count := 1 TO NumGuesses DO
BEGIN
IF (WrongHintLetter1 = GuessArray[Count])
THEN
Loop := TRUE
END;
FOR Count := 1 TO WordLength DO
BEGIN
TempLetter := COPY (WordToBeGuessed, Count, 1);
IF (WrongHintLetter1 = TempLetter)
THEN
Loop := TRUE
END
UNTIL NOT(Loop);
REPEAT
Loop := FALSE; (* Makes sure letter chosen is not *)
RANDOMIZE; (* correct or already guessed. *)
RandomNum := RANDOM(AlphabetLength) + 1;
WrongHintLetter2 := COPY (Alphabet, RandomNum, 1);
IF ((WrongHintLetter2 = CorrectHintLetter) OR (WrongHintLetter2 = WrongHintLetter1))
THEN
Loop := TRUE;
FOR Count := 1 TO NumGuesses DO
BEGIN
IF (WrongHintLetter2 = GuessArray[Count])
THEN
Loop := TRUE
END;
FOR Count := 1 TO WordLength DO
BEGIN
TempLetter := COPY (WordToBeGuessed, Count, 1);
IF (WrongHintLetter2 = TempLetter)
THEN
Loop := TRUE
END
UNTIL NOT(Loop);
OUTTEXTXY (1, 140, 'Three letters have been chosen at random.');
OUTTEXTXY (1, 160, 'One of the three is correct.');
OUTTEXTXY (1, 180, 'Make your choice.');
SETCOLOR (MAGENTA);
RANDOMIZE;
RandomNum := RANDOM (3) + 1;
IF (RandomNum = 1) (* Displays the three letters in random order. *)
THEN
OUTTEXTXY (1, 220, CorrectHintLetter + ' ' + WrongHintLetter1 + ' ' + WrongHintLetter2)
ELSE IF (RandomNum = 2)
THEN
OUTTEXTXY (1, 220, WrongHintLetter1 + ' ' + CorrectHintLetter + ' ' + WrongHintLetter2)
ELSE OUTTEXTXY (1, 220, WrongHintLetter1 + ' ' + WrongHintLetter2 + ' ' + CorrectHintLetter);
SETCOLOR (WHITE)
END;
(*----------------------------------------------------------------*)
PROCEDURE EraseHintProcedure;
(* This procedure erases all letter output leftover from the Hint procedure. *)
BEGIN
SETCOLOR (BLACK);
OUTTEXTXY (1, 140, 'Three letters have been chosen at random.');
OUTTEXTXY (1, 160, 'One of the three is correct.');
OUTTEXTXY (1, 180, 'Make your choice.');
OUTTEXTXY (1, 220, '█ █ █');
SETCOLOR (WHITE)
END;
(*----------------------------------------------------------------*)
PROCEDURE GuessCompleteWord( OldGuess:
CHAR;
WordToBeGuessed:
StringType32;
VAR Won,
Continue,
InvalidWord,
AnotherHangmanPart,
EraseInvalidMessage:
BOOLEAN;
WordLength:
INTEGER );
(* This procedure allows the user to guess the whole word at once. *)
CONST
Enter = #13;
BackSpace = #8;
TYPE
StringType50 = STRING[50];
VAR
Count,
WordSize:
INTEGER;
WordDone:
BOOLEAN;
BackSpaceLetter:
StringType1;
TempLetterGuess:
CHAR;
WordGuess:
StringType50;
BEGIN
WordSize := 0;
WordDone := FALSE;
WordGuess := '';
SETCOLOR (BLACK);
OUTTEXTXY (20, 440, OldGuess);
OUTTEXTXY (1, 400, 'Please enter a letter for your guess.');
OUTTEXTXY (1, 420, '(F1 for a hint. F2 to guess the whole word.)');
SETCOLOR (WHITE);
OUTTEXTXY (1, 380, 'Please enter the word for your guess.');
OUTTEXTXY (1, 400, 'Type in your guess and press enter.');
OUTTEXTXY (1, 420, '(Just press return to exit without guessing.)');
MOVETO (20, 440);
(* This REPEAT-UNTIL is my personal favorite. Graphics mode does not have *)
(* a READLN statement. I emulated a READLN statement by allowing the user *)
(* to input using READKEY. Then I display that letter and add it to the *)
(* word string. *)
REPEAT
TempLetterGuess := READKEY;
TempLetterGuess := UPCASE(TempLetterGuess);
IF ((TempLetterGuess >= 'A') AND (TempLetterGuess <= 'Z') AND NOT(TempLetterGuess = #0))
THEN
BEGIN
OUTTEXTXY ((WordSize * 8) + 20, 440, TempLetterGuess);
WordSize := WordSize + 1;
WordGuess := WordGuess + TempLetterGuess
END
ELSE IF ((TempLetterGuess = ' ') OR (TempLetterGuess =',') OR (TempLetterGuess = '.'))
THEN
BEGIN
OUTTEXTXY ((WordSize * 8) + 20, 440, TempLetterGuess);
WordSize := WordSize + 1;
WordGuess := WordGuess + TempLetterGuess
END
ELSE IF (TempLetterGuess = Enter)
THEN
WordDone := TRUE
ELSE IF (TempLetterGuess = BackSpace)
THEN
BEGIN
IF NOT(WordSize = 0)
THEN
BEGIN
BackSpaceLetter := COPY (WordGuess, WordSize, 1);
SETCOLOR (BLACK);
OUTTEXTXY (((WordSize - 1) * 8) + 20, 440, BackSpaceLetter);
SETCOLOR (WHITE);
WordSize := WordSize - 1;
WordGuess := COPY(WordGuess, 1, WordSize)
END
END;
UNTIL ((WordDone) OR (WordSize >= 50));
SETCOLOR (BLACK);
OUTTEXTXY (1, 380, 'Please enter the word for your guess.');
OUTTEXTXY (1, 400, 'Type in your guess and press enter.');
OUTTEXTXY (1, 420, '(Just press return to exit without guessing.)');
OUTTEXTXY (20, 440, WordGuess);
SETCOLOR (WHITE);
OUTTEXTXY (1, 400, 'Please enter a letter for your guess.');
OUTTEXTXY (1, 420, '(F1 for a hint. F2 to guess the whole word.)');
(* This IF statement set boolean variables that relay *)
(* if the answer was correct or not. *)
IF (WordSize >= 50)
THEN
BEGIN
InvalidWord := TRUE;
EraseInvalidMessage := TRUE;
OUTTEXTXY (1, 140, 'The word you entered is too long.');
OUTTEXTXY (1, 160, 'Please try again.')
END
ELSE IF (WordSize = 0)
THEN
BEGIN
InvalidWord := FALSE;
AnotherHangmanPart := FALSE
END
ELSE
BEGIN
InvalidWord := FALSE;
IF (WordGuess = WordToBeGuessed)
THEN
BEGIN
Won := True;
Continue := FALSE;
AnotherHangmanPart := FALSE;
SETCOLOR (BLACK);
MOVETO (1, 300);
FOR Count := 1 TO WordLength DO
BEGIN
OUTTEXTXY (((Count - 1) * 8) + 1, 300, '-');
END;
SETCOLOR (WHITE);
OUTTEXTXY (1, 300, WordToBeGuessed)
END
ELSE
BEGIN
AnotherHangmanPart := TRUE;
CONTINUE := False
END
END
END;
(*----------------------------------------------------------------*)
PROCEDURE EraseInvalidMessageProcedure;
(* This procedure erases the error message that *)
(* may have been left by the GuessWord procedure. *)
BEGIN
SETCOLOR (BLACK);
OUTTEXTXY (1, 140, 'The word you entered is too long.');
OUTTEXTXY (1, 160, 'Please try again.');
SETCOLOR (WHITE)
END;
(*----------------------------------------------------------------*)
PROCEDURE Guessing ( NumPartsHangman,
NumCorrectGuesses,
WordLength:
INTEGER;
GuessArray:
GuessArrayType;
WordToBeGuessed:
StringType32;
VAR Won:
BOOLEAN;
CorrectGuessArray:
CorrectGuessArrayType);
(* This procedure is the heart of the program. *)
(* It runs all guessing that the user does. *)
VAR
TempLetter:
StringType1;
Count,
StringPosition,
NumGuesses:
INTEGER;
InvalidWord,
AnotherHangmanPart,
EraseInvalidMessage,
EraseHint,
Continue,
CorrectGuess,
RepeatGuess:
BOOLEAN;
OldGuess,
Guess:
CHAR;
BEGIN
EraseHint := FALSE;
OldGuess := ' ';
NumGuesses := 0;
Continue := TRUE;
WHILE (Continue) DO (* This WHILE loop contains *)
BEGIN (* the entire guessing procedure. *)
RepeatGuess := FALSE;
Guess := READKEY;
IF (EraseHint)
THEN (* Erases leftovers from Hint procedure if present. *)
BEGIN
EraseHintProcedure;
EraseHint := FALSE
END;
Guess := UPCASE(Guess);
IF ((Guess >= 'A') AND (Guess <= 'Z') AND NOT(Guess = '#0'))
THEN (* If a letter was pressed, this IF *)
BEGIN (* checks if it belongs in the word.*)
IF (NumGuesses >= 1)
THEN
BEGIN (* Validates guess isn't a repeated guess. *)
FOR Count := 1 TO NumGuesses DO
BEGIN
IF (Guess = GuessArray[Count])
THEN
RepeatGuess := TRUE;
END
END;
IF NOT(RepeatGuess)
THEN
BEGIN
SETCOLOR (BLACK);
OUTTEXTXY (20, 440, OldGuess);
SETCOLOR (WHITE);
OUTTEXTXY (20, 440, Guess); (* Displays user's guess. *)
NumGuesses := NumGuesses + 1; GuessArray[NumGuesses] := Guess;
SETCOLOR (LIGHTCYAN);
OUTTEXTXY ((NumGuesses * 20), 30, Guess);
SETCOLOR (WHITE);
OldGuess := Guess;
CorrectGuess := FALSE;
FOR StringPosition := 1 TO WordLength DO
(* This FOR loop *) BEGIN
(* checks if the *) TempLetter := COPY (WordToBeGuessed, StringPosition, 1);
(* guessed letter *) IF (Guess = TempLetter)
(* is in the word *) THEN
(* to be guessed. *) BEGIN
(* If so, it displays *) SETCOLOR (BLACK);
(* the letter in the *) OUTTEXTXY (((StringPosition - 1)* 8)+ 1, 300, '-');
(* correct place in *) SETCOLOR (WHITE);
(* the dashes. *) OUTTEXTXY (((StringPosition - 1)* 8)+ 1, 300, TempLetter);
NumCorrectGuesses := NumCorrectGuesses + 1;
CorrectGuess := TRUE;
CorrectGuessArray[NumCorrectGuesses] := TempLetter
END
END;
IF NOT(CorrectGuess)
THEN
(* If not a correct *) BEGIN
(* guess, a piece of *) DrawHangmanParts(NumPartsHangman);
(* the hangman is *) NumPartsHangman := NumPartsHangman + 1
(* drawn. *) END;
Continue := ((NumCorrectGuesses < WordLength) AND (NumPartsHangman < 9));
IF NOT(Continue)
THEN (* Validates if user won or not. *)
BEGIN
IF (NumCorrectGuesses = WordLength)
THEN
Won := TRUE
ELSE
Won := FALSE
END
END
END
ELSE IF (Guess = #0)
THEN (* If the user's choice was a function key or *)
BEGIN (* other similar key it checks for F1 and F2. *)
Guess := READKEY;
IF (Guess = F1)
THEN
BEGIN
(* Runs the hint *) LetterHint(WordToBeGuessed, CorrectGuessArray, GuessArray,
(* procedure. *) WordLength, NumCorrectGuesses, NumGuesses);
EraseHint := TRUE
END
ELSE IF (Guess = F2)
THEN
BEGIN
EraseInvalidMessage := FALSE;
REPEAT
(* Runs the guess *) GuessCompleteWord(OldGuess, WordToBeGuessed, Won, Continue,
(* word procedure. *) InvalidWord, AnotherHangmanPart, EraseInvalidMessage, WordLength);
UNTIL NOT(InvalidWord);
IF (EraseInvalidMessage)
THEN
BEGIN
EraseInvalidMessageProcedure;
EraseInvalidMessage := FALSE
END;
IF (AnotherHangmanPart)
THEN
BEGIN
DrawHangmanParts(NumPartsHangman);
NumPartsHangman := NumPartsHangman + 1
END
END
END
END
END;
(*----------------------------------------------------------------*)
PROCEDURE PostGuessingMessage( WordToBeGuessed:
StringType32;
Won:
BOOLEAN;
NextScreen:
CHAR );
(* This procedure displays an appropriate message if the user won or lost. *)
BEGIN
IF (Won)
THEN
BEGIN
OUTTEXTXY (1, 150, 'Congratulations on a well-played game!');
OUTTEXTXY (1, 170, 'You won this time, but can you win again?')
END
ELSE
BEGIN
SETCOLOR (BLACK);
CIRCLE (365, 155, 3); (*Right Eye*)
CIRCLE (395, 155, 3); (*Left Eye*)
SETCOLOR (WHITE);
OUTTEXTXY (362, 151, 'X');
OUTTEXTXY (392, 151, 'X');
OUTTEXTXY (1, 150, 'Sorry but you did not stop Zeb');
OUTTEXTXY (1, 170, ' from being hung.');
OUTTEXTXY (1, 190, 'The correct word is ' + WordToBeGuessed + '.')
END;
SETCOLOR (RED);
OUTTEXTXY (1, 230, 'Press any key to continue.');
SETCOLOR (WHITE);
NextScreen := READKEY;
IF (NextScreen = #0)
THEN
NextScreen := READKEY
END;
(*----------------------------------------------------------------*)
PROCEDURE DesirePlayAgain(VAR PlayAgain:
CHAR;
EntryError,
Continue:
BOOLEAN;
NextScreen:
CHAR );
(* This procedure obtain the user's choice to play again or not. *)
BEGIN
RESTORECRTMODE;
EntryError := FALSE;
REPEAT
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('Would you like to play again (Y or N)? (F1 for help).');
IF (EntryError)
THEN (* Displays error message if needed. *)
BEGIN
WRITELN;
WRITELN('You have entered an invalid code.');
WRITELN('Please reenter your choice.')
END;
PlayAgain := READKEY;
IF (PlayAgain = #0)
THEN
BEGIN
PlayAgain := READKEY;
IF (PlayAgain = F1)
THEN (* Obtains if user asked for help. *)
BEGIN
PlayAgainHelp(NextScreen);
EntryError := FALSE;
Continue := FALSE
END
END
ELSE IF ((PlayAgain = 'Y') OR (PlayAgain = 'y') OR (PlayAgain = 'N') OR (PlayAgain = 'n'))
THEN
BEGIN
EntryError := FALSE; (* Decides if user played again *)
Continue := TRUE; (* or not. *)
END
ELSE
BEGIN
EntryError := TRUE;
Continue := FALSE
END
UNTIL (Continue)
END;
(*----------------------------------------------------------------*)
PROCEDURE PlayTheGame ( Category,
DifficultyLevel,
PlayAgain,
NextScreen:
CHAR;
WordToBeGuessed:
StringType32;
EntryError,
Continue:
BOOLEAN;
WordRecArray:
WordRecArrayType;
GuessArray:
GuessArrayType );
(* This procedure runs the whole user interface of the game. *)
(* It calls all the procedures to run the game part itself. *)
VAR
CorrectGuessArray:
CorrectGuessArrayType;
Won:
BOOLEAN;
NumCorrectGuesses,
WordLength,
NumPartsHangman:
INTEGER;
BEGIN
PlayAgain := 'Y';
WHILE (PlayAgain = 'y') OR (PlayAgain = 'Y') DO
BEGIN
Options(Category, DifficultyLevel, NextScreen, EntryError, Continue);
GetWord(WordToBeGuessed, Category, DifficultyLevel, WordRecArray);
SetUp(NumPartsHangman, NumCorrectGuesses, WordLength, Category,
DifficultyLevel, WordToBeGuessed, CorrectGuessArray);
Guessing(NumPartsHangman, NumCorrectGuesses, WordLength, GuessArray,
WordToBeGuessed, Won, CorrectGuessArray);
PostGuessingMessage(WordToBeGuessed, Won, NextScreen);
DesirePlayAgain(PlayAgain, EntryError, Continue, NextScreen)
END
END;
(*----------------------------------------------------------------*)
PROCEDURE Finalize( NextScreen:
CHAR );
(* Thanks the user for playing. *)
BEGIN
CLRSCR;
WRITELN;
WRITELN(' HANGMAN');
WRITELN;
WRITELN;
WRITELN('I hope you enjoyed this game. Thank you for playing.');
WRITELN('Please play again soon.');
WRITELN;
WRITELN;
WRITELN('Press any key to exit.');
NextScreen := READKEY
END;
(*------------------------ Main Program -------------------------*)
BEGIN
Introduction(WordRecArray, NextScreen);
PlayTheGame(Category, DifficultyLevel, PlayAgain, NextScreen,
WordToBeGuessed, EntryError, Continue, WordRecArray, GuessArray);
Finalize(NextScreen) (* RIP ZEB *)
END.